package com.ruoyi.web.controller.post.controller;

import java.util.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.math.BigDecimal;
import java.util.stream.Collectors;
import java.io.BufferedReader;
import java.io.InputStreamReader;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.github.pagehelper.PageHelper;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.web.controller.post.domain.Post;
import com.ruoyi.web.controller.post.domain.PostComment;
import com.ruoyi.web.controller.post.domain.PostFavorite;
import com.ruoyi.web.controller.post.domain.PostTag;
import com.ruoyi.web.controller.post.domain.PostPayment;
import com.ruoyi.web.controller.post.domain.PostReport;
import com.ruoyi.web.controller.post.domain.PostRecommendationHistory;
import com.ruoyi.web.controller.post.service.IPostCommentService;
import com.ruoyi.web.controller.post.service.IPostFavoriteService;
import com.ruoyi.web.controller.post.service.IPostService;
import com.ruoyi.web.controller.post.service.IPostTagService;
import com.ruoyi.web.controller.post.service.IPostRecommendationService;
import com.ruoyi.web.controller.post.mapper.PostPaymentMapper;
import com.ruoyi.web.controller.post.mapper.PostReportMapper;

/**
 * 帖子中心控制器，面向前端用户（重构版 - 修复推荐逻辑）
 *
 * @author thunderhub
 */
@RestController
@RequestMapping("/post-center")
public class PostCenterController extends BaseController
{
    @Autowired
    private IPostService postService;

    @Autowired
    private IPostTagService postTagService;

    @Autowired
    private IPostCommentService postCommentService;

    @Autowired
    private IPostFavoriteService postFavoriteService;

    @Autowired
    private IPostRecommendationService postRecommendationService;

    @Autowired
    private PostPaymentMapper postPaymentMapper;

    @Autowired
    private PostReportMapper postReportMapper;

    /**
     * 获取帖子列表
     */
    @Anonymous
    @GetMapping("/list")
    public TableDataInfo list(Post post,
                              @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
                              @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
                              @RequestParam(value = "tags", required = false) String tags)
    {
        // 手动设置分页参数 - 确保分页参数正确传递
        PageHelper.startPage(pageNum, pageSize);

        // 只查询状态为正常的帖子
        if (post.getStatus() == null) {
            post.setStatus("1");
        }

        // 如果有标签筛选参数，设置到查询条件中
        if (tags != null && !tags.trim().isEmpty() && !"all".equals(tags)) {
            post.setTags(tags);
        }

        List<Post> list = postService.selectPostList(post);
        return getDataTable(list);
    }

    /**
     * 获取推广帖子列表（用于轮播展示）
     */
    @Anonymous
    @GetMapping("/promotion")
    public AjaxResult getPromotionPosts()
    {
        Post query = new Post();
        query.setStatus("1"); // 只查询已发布的帖子

        List<Post> allPosts = postService.selectPostList(query);

        // 筛选出购买了最高等级推广（promotionPlanId = 1）的帖子用于轮播
        List<Post> carouselPosts = allPosts.stream()
                .filter(post -> post.getPromotionPlanId() != null && post.getPromotionPlanId().equals(1L))
                .limit(5) // 限制轮播数量
                .collect(java.util.stream.Collectors.toList());

        return success(carouselPosts);
    }
    /**
     * 获取推荐帖子列表（修复版 - 正确使用type参数，保持完全兼容）
     */
    @Anonymous
    @GetMapping("/recommendations")
    public AjaxResult getRecommendations(@RequestParam(value = "type", defaultValue = "likes") String type,
                                         @RequestParam(value = "category", required = false) String category,
                                         @RequestParam(value = "keyword", required = false) String keyword)
    {
        logger.info("=== 推荐接口调用开始 ===");
        logger.info("接收到的参数 - type: {}, category: {}, keyword: {}", type, category, keyword);

        // 获取当前用户ID（如果已登录）
        Long userId = null;
        try {
            userId = getUserId();
            logger.info("用户ID: {}", userId);
        } catch (Exception e) {
            // 用户未登录，继续使用null
            logger.info("用户未登录");
        }

        try {
            List<Post> recommendedPosts;

            // 根据type参数选择对应的推荐方法（确保调用现有的方法）
            switch (type.toLowerCase()) {

                case "smart":
                    // 使用个性化推荐（调用现有方法）
                    logger.info("使用个性化推荐算法");
                    recommendedPosts = postRecommendationService.getPersonalizedRecommendedPostsWithFilter(
                            userId, 8, category, keyword); // 0表示不限制数量
                    break;


                default:
                    // 使用基于点赞数的推荐（调用现有方法）
                    logger.info("使用基于点赞数的推荐算法");
                    recommendedPosts = postRecommendationService.getRecommendedPostsByLikesWithFilter(
                            userId, 0, category, keyword); // 0表示不限制数量
                    break;
            }

            logger.info("推荐算法返回帖子数量: {}", recommendedPosts.size());

            // 获取用户访问过的帖子ID集合（保持原有逻辑）
            Set<Long> visitedPostIds = new HashSet<>();
            if (userId != null) {
                List<Long> visitedIds = postRecommendationService.getVisitedPostIds(userId);
                visitedPostIds.addAll(visitedIds);
                logger.info("用户已访问的帖子数量: {}", visitedPostIds.size());
            }

            // 标记帖子的访问状态和推广状态（保持原有格式）
            for (Post post : recommendedPosts) {
                boolean isPromoted = post.getPromotionPlanId() != null && post.getPromotionPlanId() > 0;
                post.setRemark(isPromoted ? "promoted" : "normal"); // 使用remark字段临时标记
            }

            // 构建返回结果（保持原有格式）
            Map<String, Object> result = new HashMap<>();
            result.put("posts", recommendedPosts);
            result.put("type", type);
            result.put("total", recommendedPosts.size());
            result.put("hasMore", false); // 一次性显示所有，不再分页

            // 添加筛选信息到返回结果（保持原有逻辑）
            Map<String, Object> filters = new HashMap<>();
            if (category != null && !category.trim().isEmpty() && !"all".equals(category)) {
                filters.put("category", category);
            }
            if (keyword != null && !keyword.trim().isEmpty()) {
                filters.put("keyword", keyword);
            }
            if (!filters.isEmpty()) {
                result.put("filters", filters);
            }

            // 添加推荐统计信息（保持原有格式）
            Map<String, Object> stats = new HashMap<>();
            stats.put("userId", userId != null ? userId : "anonymous");
            stats.put("recommendationType", type);
            stats.put("returnedCount", recommendedPosts.size());
            stats.put("hasFilters", !filters.isEmpty());
            stats.put("visitedCount", visitedPostIds.size());
            result.put("stats", stats);

            logger.info("推荐接口调用成功 - 用户: {}, 类型: {}, 分类: {}, 关键词: {}, 返回数量: {}",
                    userId, type, category, keyword, recommendedPosts.size());
            logger.info("=== 推荐接口调用结束 ===");

            return success(result);

        } catch (Exception e) {
            logger.error("获取推荐帖子时发生错误", e);

            // 降级处理：返回基础帖子列表（保持原有降级逻辑）
            try {
                Post fallbackQuery = new Post();
                fallbackQuery.setStatus("1");
                List<Post> fallbackPosts = postService.selectPostList(fallbackQuery);

                Map<String, Object> fallbackResult = new HashMap<>();
                fallbackResult.put("posts", fallbackPosts.stream().limit(20).collect(Collectors.toList()));
                fallbackResult.put("type", type);
                fallbackResult.put("total", fallbackPosts.size());
                fallbackResult.put("hasMore", false);
                fallbackResult.put("error", "推荐服务异常，已降级到基础列表");

                return success(fallbackResult);
            } catch (Exception fallbackError) {
                logger.error("降级查询也失败了", fallbackError);
                return error("获取推荐内容失败，请稍后重试");
            }
        }
    }

    /**
     * 清除用户浏览历史（新增功能）
     */
    @PostMapping("/clear-history")
    public AjaxResult clearVisitHistory()
    {
        // 检查用户是否登录
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            return error("请先登录");
        }

        if (userId == null) {
            return error("请先登录");
        }

        try {
            // 清理用户所有访问记录
            int cleanedCount = postRecommendationService.cleanExpiredVisitHistory(userId, 0); // 0天表示清理所有记录

            Map<String, Object> result = new HashMap<>();
            result.put("cleanedCount", cleanedCount);
            result.put("message", "成功清理了 " + cleanedCount + " 条浏览记录");

            return success(result);
        } catch (Exception e) {
            logger.error("清除浏览历史失败，userId: {}", userId, e);
            return error("清除浏览历史失败，请稍后重试");
        }
    }

    /**
     * 获取帖子详情（修改版，增加访问记录功能）
     */
    @Anonymous
    @GetMapping("/{postId}")
    public AjaxResult getDetail(@PathVariable Long postId)
    {
        Map<String, Object> result = new HashMap<>();

        // 更新浏览量
        postService.updatePostViews(postId);

        // 获取帖子信息
        Post post = postService.selectPostById(postId);
        if (post == null || !"1".equals(post.getStatus())) {
            return error("帖子不存在或已下架");
        }
        result.put("post", post);

        // 记录用户访问历史（如果用户已登录）
        try {
            Long userId = getUserId();
            if (userId != null) {
                // 异步记录访问历史，不影响主流程
                postRecommendationService.recordUserVisit(userId, postId, "0");
            }
        } catch (Exception e) {
            // 记录访问历史失败不影响主流程，只记录日志
            logger.warn("记录用户访问历史失败，postId: {}", postId);
        }

        // 获取帖子标签
        List<PostTag> tags = postTagService.selectPostTagsByPostId(postId);
        result.put("tags", tags);

        // 获取评论，只返回顶级评论，限制10条
        List<PostComment> comments = postCommentService.selectCommentsByPostId(postId, 10);

        // 获取每个评论的回复
        List<Map<String, Object>> commentList = new ArrayList<>();
        for (PostComment comment : comments) {
            if ("1".equals(comment.getStatus())) { // 只返回正常状态的评论
                Map<String, Object> commentMap = new HashMap<>();
                commentMap.put("comment", comment);

                List<PostComment> replies = postCommentService.selectCommentsByParentId(comment.getCommentId());
                // 过滤回复，只返回正常状态的回复
                List<PostComment> validReplies = new ArrayList<>();
                for (PostComment reply : replies) {
                    if ("1".equals(reply.getStatus())) {
                        validReplies.add(reply);
                    }
                }
                commentMap.put("replies", validReplies);
                commentList.add(commentMap);
            }
        }
        result.put("comments", commentList);

        // 获取智能推荐帖子（替换原有的简单推荐逻辑）
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            // 用户未登录
        }

        List<Post> recommendedPosts = postRecommendationService.getSmartRecommendedPosts(userId, 9, post.getTags());
        result.put("recommendedPosts", recommendedPosts);

        // 判断当前用户是否已收藏
        if (userId != null) {
            PostFavorite favorite = postFavoriteService.selectPostFavoriteByPostIdAndUserId(postId, userId);
            result.put("favorited", favorite != null && "0".equals(favorite.getStatus()));
        } else {
            result.put("favorited", false);
        }

        return success(result);
    }

    /**
     * 记录推荐点击（新增功能）
     */
    @PostMapping("/recommendation-click/{postId}")
    public AjaxResult recordRecommendationClick(@PathVariable Long postId)
    {
        // 检查用户是否登录
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            // 未登录用户也可以点击推荐，但不记录历史
            return success("推荐点击记录成功（未登录）");
        }

        if (userId == null) {
            return success("推荐点击记录成功（未登录）");
        }

        // 记录推荐点击
        int result = postRecommendationService.recordUserVisit(userId, postId, "1");

        if (result > 0) {
            return success("推荐点击记录成功");
        } else {
            return error("推荐点击记录失败");
        }
    }

    /**
     * 获取用户访问历史（新增功能）
     */
    @GetMapping("/visit-history")
    public AjaxResult getVisitHistory(@RequestParam(value = "limit", defaultValue = "20") int limit)
    {
        // 检查用户是否登录
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            return error("请先登录");
        }

        if (userId == null) {
            return error("请先登录");
        }

        // 获取用户最近访问历史
        List<PostRecommendationHistory> visitHistory = postRecommendationService.getRecentVisitHistory(userId, limit);

        Map<String, Object> result = new HashMap<>();
        result.put("history", visitHistory);
        result.put("total", visitHistory.size());

        return success(result);
    }

    /**
     * 清理访问历史（新增功能）
     */
    @PostMapping("/clean-history")
    public AjaxResult cleanVisitHistory(@RequestParam(value = "days", defaultValue = "30") int days)
    {
        // 检查用户是否登录
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            return error("请先登录");
        }

        if (userId == null) {
            return error("请先登录");
        }

        // 清理过期访问记录
        int cleanedCount = postRecommendationService.cleanExpiredVisitHistory(userId, days);

        Map<String, Object> result = new HashMap<>();
        result.put("cleanedCount", cleanedCount);
        result.put("message", "清理了 " + cleanedCount + " 条过期访问记录");

        return success(result);
    }

    /**
     * 添加评论
     */
    @PostMapping("/comment")
    public AjaxResult addComment(@RequestBody PostComment postComment)
    {
        if (postComment.getPostId() == null) {
            return error("帖子ID不能为空");
        }

        if (postComment.getContent() == null || postComment.getContent().trim().isEmpty()) {
            return error("评论内容不能为空");
        }

        // 检查用户是否登录
        Long userId = null;
        String username = null;
        try {
            userId = getUserId();
            username = getUsername();
        } catch (Exception e) {
            return error("请先登录后再评论");
        }

        if (userId == null) {
            return error("请先登录后再评论");
        }

        postComment.setCreateBy(username);
        postComment.setUserId(userId);
        postComment.setUserName(username);
        postComment.setLikes(0L);
        postComment.setStatus("1"); // 默认正常状态

        // 如果父评论ID为空，设置为0（顶级评论）
        if (postComment.getParentId() == null) {
            postComment.setParentId(0L);
        }

        int result = postCommentService.insertPostComment(postComment);

        if (result > 0) {
            // 更新帖子评论数
            postService.updatePostComments(postComment.getPostId(), 1);

            // 返回新添加的评论，包括评论ID
            return success(postCommentService.selectPostCommentById(postComment.getCommentId()));
        } else {
            return error("添加评论失败");
        }
    }

    /**
     * 收藏/取消收藏帖子
     */
    @PostMapping("/favorite/{postId}")
    public AjaxResult toggleFavorite(@PathVariable Long postId, @RequestParam(required = false, defaultValue = "true") boolean favorite)
    {
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            // 用户未登录
            return error("请先登录");
        }

        if (userId == null) {
            return error("请先登录");
        }

        // 检查帖子是否存在
        Post post = postService.selectPostById(postId);
        if (post == null || !"1".equals(post.getStatus())) {
            return error("帖子不存在或已下架");
        }

        // 检查是否已收藏
        PostFavorite exist = postFavoriteService.selectPostFavoriteByPostIdAndUserId(postId, userId);

        Map<String, Object> resultData = new HashMap<>();
        resultData.put("favorited", favorite);

        if (favorite) {
            // 收藏操作
            if (exist != null) {
                // 已存在记录，检查状态
                if ("0".equals(exist.getStatus())) {
                    return AjaxResult.success("已收藏该帖子");
                } else {
                    // 取消收藏状态，改为收藏状态
                    exist.setStatus("0");
                    exist.setUpdateBy(getUsername());
                    postFavoriteService.updatePostFavorite(exist);

                    // 更新帖子收藏数量
                    postService.updatePostFavorites(postId, 1);

                    return AjaxResult.success("收藏成功");
                }
            } else {
                // 创建收藏记录
                PostFavorite favoriteRecord = new PostFavorite();
                favoriteRecord.setPostId(postId);
                favoriteRecord.setUserId(userId);
                favoriteRecord.setPostTitle(post.getTitle());
                favoriteRecord.setPostCover(post.getCoverImage());
                favoriteRecord.setStatus("0");
                favoriteRecord.setCreateBy(getUsername());
                postFavoriteService.insertPostFavorite(favoriteRecord);

                // 更新帖子收藏数量
                postService.updatePostFavorites(postId, 1);

                return AjaxResult.success("收藏成功");
            }
        } else {
            // 取消收藏操作
            if (exist != null && "0".equals(exist.getStatus())) {
                // 更新为取消收藏状态
                exist.setStatus("1");
                exist.setUpdateBy(getUsername());
                postFavoriteService.updatePostFavorite(exist);

                // 更新帖子收藏数量
                postService.updatePostFavorites(postId, -1);

                return AjaxResult.success("取消收藏成功");
            } else {
                return AjaxResult.success("未收藏该帖子");
            }
        }
    }

    /**
     * 获取热门标签
     */
    @Anonymous
    @GetMapping("/tags/hot")
    public AjaxResult getHotTags(@RequestParam(required = false, defaultValue = "10") int limit)
    {
        // 获取帖子数量最多的标签
        PostTag query = new PostTag();
        query.setStatus("0"); // 正常状态

        // 使用startPage方法
        startPage();

        // 手动限制结果数量
        List<PostTag> allTags = postTagService.selectPostTagList(query);
        List<PostTag> sortedTags = allTags.stream()
                .sorted((a, b) -> b.getPostCount().compareTo(a.getPostCount()))
                .limit(limit)
                .collect(java.util.stream.Collectors.toList());

        return AjaxResult.success(sortedTags);
    }

    /**
     * 根据标签获取帖子
     */
    @Anonymous
    @GetMapping("/bytag/{tagId}")
    public TableDataInfo getPostsByTag(@PathVariable Long tagId)
    {
        startPage();
        // 查询该标签的所有帖子
        // 假设已经实现了这个方法
        // 实际情况下，可能需要通过关联表查询
        PostTag tag = postTagService.selectPostTagById(tagId);

        if (tag == null) {
            return getDataTable(new ArrayList<>());
        }

        Post query = new Post();
        query.setTags(tag.getTagName());
        query.setStatus("1"); // 只查询正常状态的帖子
        List<Post> posts = postService.selectPostList(query);

        return getDataTable(posts);
    }

    /**
     * 发布新帖子
     */
    @PostMapping("/publish")
    public AjaxResult publishPost(@RequestBody Post post)
    {
        // 检查用户是否登录
        Long userId = null;
        String username = null;
        try {
            userId = getUserId();
            username = getUsername();
        } catch (Exception e) {
            return error("请先登录后再发布帖子");
        }

        if (userId == null) {
            return error("请先登录后再发布帖子");
        }

        // 验证必填字段
        if (post.getTitle() == null || post.getTitle().trim().isEmpty()) {
            return error("帖子标题不能为空");
        }

        if (post.getSummary() == null || post.getSummary().trim().isEmpty()) {
            return error("帖子摘要不能为空");
        }
        
        // 设置帖子类型，如果未设置，默认为图文帖子
        if (post.getPostType() == null || post.getPostType().trim().isEmpty()) {
            post.setPostType("0"); // 默认为图文帖子
        }
        
        // 根据帖子类型验证必填字段
        if ("0".equals(post.getPostType())) { // 图文帖子
            if (post.getContent() == null || post.getContent().trim().isEmpty()) {
                return error("图文帖子内容不能为空");
            }
        } else if ("1".equals(post.getPostType())) { // 视频帖子
            if (post.getVideoUrl() == null || post.getVideoUrl().trim().isEmpty()) {
                return error("视频URL不能为空");
            }
        } else {
            return error("帖子类型无效");
        }

        // 设置帖子基本信息
        post.setAuthorId(userId);
        post.setAuthor(username);
        post.setViews(0L);
        post.setComments(0L);
        post.setFavorites(0L);
        post.setLikes(0L);
        post.setStatus("0"); // 默认待审核状态
        post.setCreateBy(username);

        // 自动设置发布时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        post.setPublishTime(sdf.format(new Date()));

        // 如果没有设置封面图，使用默认图片
        if (post.getCoverImage() == null || post.getCoverImage().trim().isEmpty()) {
            // 对于视频帖子，如果有缩略图，则使用缩略图作为封面
            if ("1".equals(post.getPostType()) && post.getVideoThumbnail() != null && !post.getVideoThumbnail().trim().isEmpty()) {
                post.setCoverImage(post.getVideoThumbnail());
            } else {
                post.setCoverImage("/images/default-cover.jpg");
            }
        }

        // 处理标签
        if (post.getTags() != null && !post.getTags().trim().isEmpty()) {
            // 这里可以处理标签逻辑，比如创建标签关联关系
            // 暂时直接保存标签字符串
        }

        int result = postService.insertPost(post);

        if (result > 0) {
            // 处理帖子与标签的关联关系
            if (post.getTags() != null && !post.getTags().trim().isEmpty()) {
                try {
                    // 解析标签字符串，格式可能是"标签1,标签2,标签3"
                    String[] tagNames = post.getTags().split(",");
                    List<Long> tagIds = new ArrayList<>();
                    
                    for (String tagName : tagNames) {
                        tagName = tagName.trim();
                        if (!tagName.isEmpty()) {
                            // 查询标签是否已存在
                            PostTag tagQuery = new PostTag();
                            tagQuery.setTagName(tagName);
                            List<PostTag> existingTags = postTagService.selectPostTagList(tagQuery);
                            
                            Long tagId;
                            if (existingTags != null && !existingTags.isEmpty()) {
                                // 标签已存在，使用现有标签
                                tagId = existingTags.get(0).getTagId();
                                // 更新标签的帖子数量
                                postTagService.updatePostTagCount(tagId, 1);
                            } else {
                                // 标签不存在，创建新标签
                                PostTag newTag = new PostTag();
                                newTag.setTagName(tagName);
                                newTag.setTagColor("blue"); // 默认颜色
                                newTag.setPostCount(1L); // 初始帖子数为1
                                newTag.setStatus("0"); // 正常状态
                                newTag.setCreateBy(username);
                                postTagService.insertPostTag(newTag);
                                tagId = newTag.getTagId();
                            }
                            
                            tagIds.add(tagId);
                        }
                    }
                    
                    // 批量插入帖子标签关联
                    if (!tagIds.isEmpty()) {
                        Long[] tagIdArray = tagIds.toArray(new Long[0]);
                        postTagService.batchInsertPostTagRelation(post.getPostId(), tagIdArray);
                    }
                } catch (Exception e) {
                    logger.error("处理帖子标签关联关系失败", e);
                    // 不影响帖子发布的主流程，仅记录错误
                }
            }
            
            // 返回新创建的帖子信息，包含postId
            Map<String, Object> data = new HashMap<>();
            data.put("postId", post.getPostId());
            data.put("message", "帖子发布成功，等待管理员审核");
            return success(data);
        } else {
            return error("帖子发布失败");
        }
    }

    /**
     * 获取当前用户的帖子列表
     */
    @GetMapping("/my-posts")
    public TableDataInfo getMyPosts(Post post,
                                   @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
                                   @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize)
    {
        // 检查用户是否登录
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            return getDataTable(new ArrayList<>());
        }

        if (userId == null) {
            return getDataTable(new ArrayList<>());
        }

        // 手动设置分页参数
        PageHelper.startPage(pageNum, pageSize);

        // 只查询当前用户的帖子
        post.setAuthorId(userId);
        List<Post> list = postService.selectPostList(post);
        return getDataTable(list);
    }

    /**
     * 获取当前用户的收藏列表
     */
    @GetMapping("/my-favorites")
    public TableDataInfo getMyFavorites(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
                                       @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize)
    {
        // 检查用户是否登录
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            return getDataTable(new ArrayList<>());
        }

        if (userId == null) {
            return getDataTable(new ArrayList<>());
        }

        // 手动设置分页参数
        PageHelper.startPage(pageNum, pageSize);

        // 查询用户收藏的帖子
        PostFavorite favoriteQuery = new PostFavorite();
        favoriteQuery.setUserId(userId);
        favoriteQuery.setStatus("0"); // 只查询有效收藏
        List<PostFavorite> favorites = postFavoriteService.selectPostFavoriteList(favoriteQuery);

        // 获取收藏的帖子详情
        List<Post> favoritePosts = new ArrayList<>();
        for (PostFavorite favorite : favorites) {
            Post post = postService.selectPostById(favorite.getPostId());
            if (post != null && "1".equals(post.getStatus())) {
                favoritePosts.add(post);
            }
        }

        return getDataTable(favoritePosts);
    }

    /**
     * 更新帖子
     */
    @PutMapping("/update")
    public AjaxResult updatePost(@RequestBody Post post)
    {
        // 检查用户是否登录
        Long userId = null;
        String username = null;
        try {
            userId = getUserId();
            username = getUsername();
        } catch (Exception e) {
            return error("请先登录");
        }

        if (userId == null) {
            return error("请先登录");
        }

        if (post.getPostId() == null) {
            return error("帖子ID不能为空");
        }

        // 检查帖子是否存在且属于当前用户
        Post existingPost = postService.selectPostById(post.getPostId());
        if (existingPost == null) {
            return error("帖子不存在");
        }

        if (!userId.equals(existingPost.getAuthorId())) {
            return error("只能编辑自己的帖子");
        }

        // 验证必填字段
        if (post.getTitle() == null || post.getTitle().trim().isEmpty()) {
            return error("帖子标题不能为空");
        }

        if (post.getContent() == null || post.getContent().trim().isEmpty()) {
            return error("帖子内容不能为空");
        }

        if (post.getSummary() == null || post.getSummary().trim().isEmpty()) {
            return error("帖子摘要不能为空");
        }

        // 设置更新信息
        post.setUpdateBy(username);

        int result = postService.updatePost(post);

        if (result > 0) {
            // 处理帖子与标签的关联关系
            if (post.getTags() != null && !post.getTags().trim().isEmpty()) {
                try {
                    // 先删除原有的标签关联
                    postTagService.deletePostTagRelation(post.getPostId());
                    
                    // 解析标签字符串，格式可能是"标签1,标签2,标签3"
                    String[] tagNames = post.getTags().split(",");
                    List<Long> tagIds = new ArrayList<>();
                    
                    for (String tagName : tagNames) {
                        tagName = tagName.trim();
                        if (!tagName.isEmpty()) {
                            // 查询标签是否已存在
                            PostTag tagQuery = new PostTag();
                            tagQuery.setTagName(tagName);
                            List<PostTag> existingTags = postTagService.selectPostTagList(tagQuery);
                            
                            Long tagId;
                            if (existingTags != null && !existingTags.isEmpty()) {
                                // 标签已存在，使用现有标签
                                tagId = existingTags.get(0).getTagId();
                                // 更新标签的帖子数量
                                postTagService.updatePostTagCount(tagId, 1);
                            } else {
                                // 标签不存在，创建新标签
                                PostTag newTag = new PostTag();
                                newTag.setTagName(tagName);
                                newTag.setTagColor("blue"); // 默认颜色
                                newTag.setPostCount(1L); // 初始帖子数为1
                                newTag.setStatus("0"); // 正常状态
                                newTag.setCreateBy(username);
                                postTagService.insertPostTag(newTag);
                                tagId = newTag.getTagId();
                            }
                            
                            tagIds.add(tagId);
                        }
                    }
                    
                    // 批量插入帖子标签关联
                    if (!tagIds.isEmpty()) {
                        Long[] tagIdArray = tagIds.toArray(new Long[0]);
                        postTagService.batchInsertPostTagRelation(post.getPostId(), tagIdArray);
                    }
                } catch (Exception e) {
                    logger.error("处理帖子标签关联关系失败", e);
                    // 不影响帖子更新的主流程，仅记录错误
                }
            }
            
            return success("帖子更新成功");
        } else {
            return error("帖子更新失败");
        }
    }

    /**
     * 删除帖子
     */
    @DeleteMapping("/delete/{postId}")
    public AjaxResult deletePost(@PathVariable Long postId)
    {
        // 检查用户是否登录
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            return error("请先登录");
        }

        if (userId == null) {
            return error("请先登录");
        }

        // 检查帖子是否存在且属于当前用户
        Post existingPost = postService.selectPostById(postId);
        if (existingPost == null) {
            return error("帖子不存在");
        }

        if (!userId.equals(existingPost.getAuthorId())) {
            return error("只能删除自己的帖子");
        }

        try {
            // 删除帖子相关的文件资源（图片、视频）
            deletePostResources(existingPost);
            
            // 如果是草稿帖子（状态为待审核"0"），直接删除，无需级联删除
            if ("0".equals(existingPost.getStatus())) {
                // 删除相关支付记录（如果有）
                postPaymentMapper.deletePostPaymentByPostId(postId);
                
                // 删除帖子标签关联关系
                postTagService.deletePostTagRelation(postId);

                // 直接删除帖子
                int result = postService.deletePostById(postId);

                if (result > 0) {
                    return success("草稿帖子删除成功");
                } else {
                    return error("草稿帖子删除失败");
                }
            } else {
                // 对于已发布的帖子，进行级联删除
                // 1. 删除帖子评论
                postCommentService.deletePostCommentByPostId(postId);

                // 2. 删除帖子收藏记录
                postFavoriteService.deletePostFavoriteByPostId(postId);

                // 3. 删除支付记录
                postPaymentMapper.deletePostPaymentByPostId(postId);
                
                // 4. 删除帖子标签关联关系
                postTagService.deletePostTagRelation(postId);

                // 5. 删除帖子本身
                int result = postService.deletePostById(postId);

                if (result > 0) {
                    return success("帖子删除成功");
                } else {
                    return error("帖子删除失败");
                }
            }
        } catch (Exception e) {
            return error("删除失败：" + e.getMessage());
        }
    }
    
    /**
     * 删除帖子相关的资源文件（图片、视频）
     */
    private void deletePostResources(Post post) {
        String projectRoot = System.getProperty("user.dir");
        String frontendImagePath = com.ruoyi.common.config.RuoYiConfig.getFrontendImagePath();
        
        if (frontendImagePath == null) {
            logger.error("前端图片路径未配置，无法删除帖子资源文件");
            return;
        }
        
        try {
            // 1. 删除封面图片
            if (post.getCoverImage() != null && !post.getCoverImage().isEmpty()) {
                String coverImagePath = post.getCoverImage();
                // 提取文件名
                if (coverImagePath.contains("/")) {
                    coverImagePath = coverImagePath.substring(coverImagePath.lastIndexOf("/") + 1);
                }
                
                // 如果不是默认图片，则删除
                if (!coverImagePath.equals("default-cover.jpg") && !coverImagePath.equals("404.png")) {
                    Path imagePath = Paths.get(projectRoot, frontendImagePath, coverImagePath);
                    if (Files.exists(imagePath)) {
                        Files.delete(imagePath);
                        logger.info("已删除帖子封面图片: " + imagePath);
                    }
                }
            }
            
            // 2. 删除视频及其缩略图（如果是视频帖子）
            if ("1".equals(post.getPostType()) && post.getVideoUrl() != null && !post.getVideoUrl().isEmpty()) {
                String videoPath = post.getVideoUrl();
                // 提取文件名
                if (videoPath.contains("/")) {
                    videoPath = videoPath.substring(videoPath.lastIndexOf("/") + 1);
                }
                
                // 删除视频文件
                if (videoPath.contains("?")) {
                    videoPath = videoPath.substring(0, videoPath.indexOf("?"));
                }
                
                Path videoFilePath = Paths.get(projectRoot, frontendImagePath, "videos", videoPath);
                if (Files.exists(videoFilePath)) {
                    Files.delete(videoFilePath);
                    logger.info("已删除帖子视频文件: " + videoFilePath);
                }
                
                // 删除视频缩略图
                String filenameWithoutExt = videoPath;
                if (filenameWithoutExt.contains(".")) {
                    filenameWithoutExt = filenameWithoutExt.substring(0, filenameWithoutExt.lastIndexOf("."));
                }
                String thumbnailFilename = "thumbnail_" + filenameWithoutExt + ".jpg";
                Path thumbnailPath = Paths.get(projectRoot, frontendImagePath, "thumbnails", thumbnailFilename);
                
                if (Files.exists(thumbnailPath)) {
                    Files.delete(thumbnailPath);
                    logger.info("已删除帖子视频缩略图: " + thumbnailPath);
                }
            }
            
            // 3. 从帖子内容中提取并删除内嵌图片
            if (post.getContent() != null && !post.getContent().isEmpty()) {
                // 使用正则表达式匹配内容中的图片URL
                java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("src=\"(/images/[^\"]+)\"");
                java.util.regex.Matcher matcher = pattern.matcher(post.getContent());
                
                while (matcher.find()) {
                    String imageUrl = matcher.group(1);
                    String imageName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);
                    
                    // 排除默认图片
                    if (!imageName.equals("default-cover.jpg") && !imageName.equals("404.png")) {
                        Path imagePath = Paths.get(projectRoot, frontendImagePath, imageName);
                        if (Files.exists(imagePath)) {
                            Files.delete(imagePath);
                            logger.info("已删除帖子内容图片: " + imagePath);
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("删除帖子资源文件失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取可用标签列表（用于下拉选择）
     */
    @Anonymous
    @GetMapping("/tags/available")
    public AjaxResult getAvailableTags()
    {
        PostTag query = new PostTag();
        query.setStatus("0"); // 正常状态
        List<PostTag> tags = postTagService.selectPostTagList(query);
        return success(tags);
    }

    /**
     * 点赞/取消点赞帖子
     */
    @PostMapping("/like/{postId}")
    public AjaxResult toggleLike(@PathVariable Long postId, @RequestParam(required = false, defaultValue = "true") boolean like)
    {
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            return error("请先登录");
        }

        if (userId == null) {
            return error("请先登录");
        }

        // 检查帖子是否存在
        Post post = postService.selectPostById(postId);
        if (post == null || !"1".equals(post.getStatus())) {
            return error("帖子不存在或已下架");
        }

        // 这里简化处理，直接更新点赞数
        // 实际应用中应该记录用户点赞状态，防止重复点赞
        if (like) {
            postService.updatePostLikes(postId, 1);
            return success("点赞成功");
        } else {
            postService.updatePostLikes(postId, -1);
            return success("取消点赞成功");
        }
    }

    /**
     * 点赞/取消点赞评论
     */
    @PostMapping("/comment/like/{commentId}")
    public AjaxResult toggleCommentLike(@PathVariable Long commentId, @RequestParam(required = false, defaultValue = "true") boolean like)
    {
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            return error("请先登录");
        }

        if (userId == null) {
            return error("请先登录");
        }

        // 检查评论是否存在
        PostComment comment = postCommentService.selectPostCommentById(commentId);
        if (comment == null || !"1".equals(comment.getStatus())) {
            return error("评论不存在或已删除");
        }

        // 这里简化处理，直接更新点赞数
        // 实际应用中应该记录用户点赞状态，防止重复点赞
        if (like) {
            postCommentService.updateCommentLikes(commentId, 1);
            return success("点赞成功");
        } else {
            postCommentService.updateCommentLikes(commentId, -1);
            return success("取消点赞成功");
        }
    }

    /**
     * 上传图片
     */
    @PostMapping("/upload")
    public AjaxResult uploadImage(@RequestParam("file") MultipartFile file)
    {
        try {
            if (file.isEmpty()) {
                return error("上传文件不能为空");
            }

            // 检查文件类型
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null) {
                return error("文件名不能为空");
            }

            String extension = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
            if (!extension.matches("(?i)\\.(jpg|jpeg|png|gif|bmp|webp)$")) {
                return error("只支持jpg、jpeg、png、gif、bmp、webp格式的图片文件");
            }

            // 检查文件大小（限制为5MB）
            if (file.getSize() > 5 * 1024 * 1024) {
                return error("文件大小不能超过5MB");
            }

            // 生成唯一文件名
            String fileName = System.currentTimeMillis() + "_" +
                             (int)(Math.random() * 1000) + extension;

            // 使用配置文件中的相对路径
            String frontendImagePath = com.ruoyi.common.config.RuoYiConfig.getFrontendImagePath();
            if (frontendImagePath == null) {
                return error("前端图片路径未配置");
            }

            // 获取项目根目录的绝对路径
            String projectRoot = System.getProperty("user.dir");
            String uploadDir = Paths.get(projectRoot, frontendImagePath).toString();

            File uploadDirFile = new File(uploadDir);
            if (!uploadDirFile.exists()) {
                uploadDirFile.mkdirs();
            }

            // 保存文件
            Path filePath = Paths.get(uploadDir, fileName);
            Files.copy(file.getInputStream(), filePath);

            // 返回访问URL - 前端可以直接通过/images/访问
            String imageUrl = "/images/" + fileName;

            Map<String, String> result = new HashMap<>();
            result.put("url", imageUrl);
            result.put("filename", fileName);
            result.put("originalName", originalFilename);
            result.put("size", String.valueOf(file.getSize()));

            return success(result);
        } catch (IOException e) {
            return error("上传失败：" + e.getMessage());
        } catch (Exception e) {
            return error("上传失败：" + e.getMessage());
        }
    }

    /**
     * 上传视频
     */
    @PostMapping("/upload/video")
    public AjaxResult uploadVideo(@RequestParam("file") MultipartFile file)
    {
        try {
            if (file.isEmpty()) {
                return error("上传文件不能为空");
            }

            // 检查文件类型
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null) {
                return error("文件名不能为空");
            }

            String extension = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
            if (!extension.matches("(?i)\\.(mp4|webm|ogg|mov|avi)$")) {
                return error("只支持mp4、webm、ogg、mov、avi格式的视频文件");
            }

            // 检查文件大小（限制为200MB）
            if (file.getSize() > 200 * 1024 * 1024) {
                return error("文件大小不能超过200MB");
            }

            // 生成唯一文件名
            String fileName = System.currentTimeMillis() + "_" +
                             (int)(Math.random() * 1000) + extension;

            // 使用配置文件中的相对路径的视频子目录
            String frontendVideoPath = com.ruoyi.common.config.RuoYiConfig.getFrontendImagePath() + "/videos";
            String thumbnailPath = com.ruoyi.common.config.RuoYiConfig.getFrontendImagePath() + "/thumbnails";
            
            // 获取项目根目录的绝对路径
            String projectRoot = System.getProperty("user.dir");
            String uploadDir = Paths.get(projectRoot, frontendVideoPath).toString();
            String thumbnailDir = Paths.get(projectRoot, thumbnailPath).toString();

            // 确保目录存在
            File uploadDirFile = new File(uploadDir);
            if (!uploadDirFile.exists()) {
                uploadDirFile.mkdirs();
            }
            
            File thumbnailDirFile = new File(thumbnailDir);
            if (!thumbnailDirFile.exists()) {
                thumbnailDirFile.mkdirs();
            }

            // 保存原始文件
            Path originalFilePath = Paths.get(uploadDir, fileName);
            Files.copy(file.getInputStream(), originalFilePath);

            // 视频处理
            int videoDuration = 0;
            String thumbnailFileName = "";
            
            try {
                // 使用FFmpeg获取视频时长
                String durationCmd = "ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 " + originalFilePath.toString();
                Process durationProcess = Runtime.getRuntime().exec(durationCmd);
                BufferedReader reader = new BufferedReader(new InputStreamReader(durationProcess.getInputStream()));
                String durationStr = reader.readLine();
                durationProcess.waitFor();
                
                if (durationStr != null && !durationStr.isEmpty()) {
                    videoDuration = (int) Math.round(Double.parseDouble(durationStr));
                } else {
                    // 如果获取失败，设置一个默认值
                    videoDuration = 0;
                }
                
                // 生成缩略图
                String filenameWithoutExt = fileName.substring(0, fileName.lastIndexOf("."));
                thumbnailFileName = "thumbnail_" + filenameWithoutExt + ".jpg";
                Path thumbnailFilePath = Paths.get(thumbnailDir, thumbnailFileName);
                
                // 使用FFmpeg生成缩略图，从视频的第1秒提取一帧
                String thumbnailCmd = "ffmpeg -i " + originalFilePath.toString() + " -ss 00:00:01 -vframes 1 " + thumbnailFilePath.toString();
                Process thumbnailProcess = Runtime.getRuntime().exec(thumbnailCmd);
                thumbnailProcess.waitFor();
                
                // 检查缩略图是否生成成功
                if (!Files.exists(thumbnailFilePath)) {
                    System.err.println("缩略图生成失败");
                }
                
            } catch (Exception e) {
                // 如果处理失败，记录错误但继续返回原始视频
                System.err.println("视频处理失败: " + e.getMessage());
                e.printStackTrace();
            }

            // 返回访问URL - 前端可以直接通过/images/videos/访问
            String videoUrl = "/images/videos/" + fileName;
            String thumbnailUrl = "/images/thumbnails/" + thumbnailFileName;

            Map<String, Object> result = new HashMap<>();
            result.put("url", videoUrl);
            result.put("filename", fileName);
            result.put("originalName", originalFilename);
            result.put("size", String.valueOf(file.getSize()));
            result.put("duration", videoDuration);
            result.put("thumbnail", thumbnailUrl);

            return success(result);
        } catch (IOException e) {
            return error("上传失败：" + e.getMessage());
        } catch (Exception e) {
            return error("上传失败：" + e.getMessage());
        }
    }
    
    /**
     * 上传视频缩略图
     */
    @PostMapping("/upload/video-thumbnail")
    public AjaxResult uploadVideoThumbnail(@RequestParam("file") MultipartFile file)
    {
        try {
            if (file.isEmpty()) {
                return error("上传文件不能为空");
            }

            // 检查文件类型
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null) {
                return error("文件名不能为空");
            }

            String extension = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
            if (!extension.matches("(?i)\\.(jpg|jpeg|png)$")) {
                return error("只支持jpg、jpeg、png格式的缩略图");
            }

            // 检查文件大小（限制为2MB）
            if (file.getSize() > 2 * 1024 * 1024) {
                return error("文件大小不能超过2MB");
            }

            // 生成唯一文件名
            String fileName = "thumbnail_" + System.currentTimeMillis() + "_" +
                             (int)(Math.random() * 1000) + extension;

            // 使用配置文件中的相对路径的视频缩略图子目录
            String thumbnailPath = com.ruoyi.common.config.RuoYiConfig.getFrontendImagePath() + "/thumbnails";
            
            // 获取项目根目录的绝对路径
            String projectRoot = System.getProperty("user.dir");
            String uploadDir = Paths.get(projectRoot, thumbnailPath).toString();

            File uploadDirFile = new File(uploadDir);
            if (!uploadDirFile.exists()) {
                uploadDirFile.mkdirs();
            }

            // 保存文件
            Path filePath = Paths.get(uploadDir, fileName);
            Files.copy(file.getInputStream(), filePath);

            // 返回访问URL
            String thumbnailUrl = "/images/thumbnails/" + fileName;

            Map<String, String> result = new HashMap<>();
            result.put("url", thumbnailUrl);
            result.put("filename", fileName);
            result.put("originalName", originalFilename);
            result.put("size", String.valueOf(file.getSize()));

            return success(result);
        } catch (IOException e) {
            return error("上传失败：" + e.getMessage());
        } catch (Exception e) {
            return error("上传失败：" + e.getMessage());
        }
    }

    /**
     * 删除图片
     */
    @DeleteMapping("/upload")
    public AjaxResult deleteImage(@RequestParam("filename") String filename)
    {
        try {
            if (filename == null || filename.trim().isEmpty()) {
                return error("文件名不能为空");
            }

            // 使用配置文件中的相对路径
            String frontendImagePath = com.ruoyi.common.config.RuoYiConfig.getFrontendImagePath();
            if (frontendImagePath == null) {
                return error("前端图片路径未配置");
            }

            // 获取项目根目录的绝对路径
            String projectRoot = System.getProperty("user.dir");
            String uploadDir = Paths.get(projectRoot, frontendImagePath).toString();
            Path filePath = Paths.get(uploadDir, filename);

            // 检查文件是否存在
            if (Files.exists(filePath)) {
                Files.delete(filePath);
                return success("图片删除成功");
            } else {
                return error("文件不存在");
            }
        } catch (IOException e) {
            return error("删除失败：" + e.getMessage());
        } catch (Exception e) {
            return error("删除失败：" + e.getMessage());
        }
    }

    /**
     * 删除视频
     */
    @DeleteMapping("/upload/video")
    public AjaxResult deleteVideo(@RequestParam("filename") String filename)
    {
        try {
            if (filename == null || filename.trim().isEmpty()) {
                return error("文件名不能为空");
            }

            // 使用配置文件中的相对路径
            String frontendVideoPath = com.ruoyi.common.config.RuoYiConfig.getFrontendImagePath() + "/videos";
            
            // 获取项目根目录的绝对路径
            String projectRoot = System.getProperty("user.dir");
            String uploadDir = Paths.get(projectRoot, frontendVideoPath).toString();
            Path filePath = Paths.get(uploadDir, filename);

            // 检查文件是否存在
            if (Files.exists(filePath)) {
                Files.delete(filePath);
                
                // 同时删除可能存在的缩略图
                String thumbnailFilename = "thumbnail_" + filename.substring(0, filename.lastIndexOf(".")) + ".jpg";
                String thumbnailPath = com.ruoyi.common.config.RuoYiConfig.getFrontendImagePath() + "/thumbnails";
                Path thumbnailFilePath = Paths.get(projectRoot, thumbnailPath, thumbnailFilename);
                
                if (Files.exists(thumbnailFilePath)) {
                    Files.delete(thumbnailFilePath);
                }
                
                return success("视频删除成功");
            } else {
                return error("文件不存在");
            }
        } catch (IOException e) {
            return error("删除失败：" + e.getMessage());
        } catch (Exception e) {
            return error("删除失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取视频信息
     */
    @GetMapping("/video/info")
    public AjaxResult getVideoInfo(@RequestParam("videoUrl") String videoUrl)
    {
        try {
            if (videoUrl == null || videoUrl.trim().isEmpty()) {
                return error("视频URL不能为空");
            }
            
            // 从URL中提取文件名
            String filename = videoUrl.substring(videoUrl.lastIndexOf("/") + 1);
            
            // 使用配置文件中的相对路径
            String frontendVideoPath = com.ruoyi.common.config.RuoYiConfig.getFrontendImagePath() + "/videos";
            
            // 获取项目根目录的绝对路径
            String projectRoot = System.getProperty("user.dir");
            String fullPath = Paths.get(projectRoot, frontendVideoPath, filename).toString();
            
            // 检查文件是否存在
            if (!Files.exists(Paths.get(fullPath))) {
                return error("视频文件不存在");
            }
            
            // 使用FFmpeg获取视频信息
            Map<String, Object> videoInfo = new HashMap<>();
            
            // 获取视频时长
            String durationCmd = "ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 " + fullPath;
            Process durationProcess = Runtime.getRuntime().exec(durationCmd);
            BufferedReader durationReader = new BufferedReader(new InputStreamReader(durationProcess.getInputStream()));
            String durationStr = durationReader.readLine();
            durationProcess.waitFor();
            
            if (durationStr != null && !durationStr.isEmpty()) {
                videoInfo.put("duration", (int) Math.round(Double.parseDouble(durationStr)));
            } else {
                videoInfo.put("duration", 0);
            }
            
            // 获取视频分辨率
            String resolutionCmd = "ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 " + fullPath;
            Process resolutionProcess = Runtime.getRuntime().exec(resolutionCmd);
            BufferedReader resolutionReader = new BufferedReader(new InputStreamReader(resolutionProcess.getInputStream()));
            String resolutionStr = resolutionReader.readLine();
            resolutionProcess.waitFor();
            
            if (resolutionStr != null && !resolutionStr.isEmpty()) {
                String[] dimensions = resolutionStr.split("x");
                if (dimensions.length == 2) {
                    videoInfo.put("width", Integer.parseInt(dimensions[0]));
                    videoInfo.put("height", Integer.parseInt(dimensions[1]));
                }
            }
            
            // 获取视频格式
            String formatCmd = "ffprobe -v error -show_entries format=format_name -of default=noprint_wrappers=1:nokey=1 " + fullPath;
            Process formatProcess = Runtime.getRuntime().exec(formatCmd);
            BufferedReader formatReader = new BufferedReader(new InputStreamReader(formatProcess.getInputStream()));
            String formatStr = formatReader.readLine();
            formatProcess.waitFor();
            
            if (formatStr != null && !formatStr.isEmpty()) {
                videoInfo.put("format", formatStr);
            }
            
            // 获取文件大小
            videoInfo.put("size", Files.size(Paths.get(fullPath)));
            
            return success(videoInfo);
        } catch (Exception e) {
            return error("获取视频信息失败：" + e.getMessage());
        }
    }
    
    /**
     * 生成视频缩略图
     */
    @PostMapping("/video/thumbnail")
    public AjaxResult generateVideoThumbnail(@RequestBody Map<String, String> request)
    {
        try {
            String videoUrl = request.get("videoUrl");
            if (videoUrl == null || videoUrl.trim().isEmpty()) {
                return error("视频URL不能为空");
            }
            
            // 从URL中提取文件名
            String filename = videoUrl.substring(videoUrl.lastIndexOf("/") + 1);
            String filenameWithoutExt = filename.substring(0, filename.lastIndexOf("."));
            
            // 使用配置文件中的相对路径
            String frontendVideoPath = com.ruoyi.common.config.RuoYiConfig.getFrontendImagePath() + "/videos";
            String thumbnailPath = com.ruoyi.common.config.RuoYiConfig.getFrontendImagePath() + "/thumbnails";
            
            // 获取项目根目录的绝对路径
            String projectRoot = System.getProperty("user.dir");
            String videoFullPath = Paths.get(projectRoot, frontendVideoPath, filename).toString();
            
            // 检查视频文件是否存在
            if (!Files.exists(Paths.get(videoFullPath))) {
                return error("视频文件不存在");
            }
            
            // 缩略图文件名
            String thumbnailFilename = "thumbnail_" + filenameWithoutExt + ".jpg";
            String thumbnailFullPath = Paths.get(projectRoot, thumbnailPath, thumbnailFilename).toString();
            
            // 确保缩略图目录存在
            File thumbnailDir = new File(Paths.get(projectRoot, thumbnailPath).toString());
            if (!thumbnailDir.exists()) {
                thumbnailDir.mkdirs();
            }
            
            // 使用FFmpeg生成缩略图，从视频的第1秒提取一帧
            String thumbnailCmd = "ffmpeg -i " + videoFullPath + " -ss 00:00:01 -vframes 1 " + thumbnailFullPath;
            Process thumbnailProcess = Runtime.getRuntime().exec(thumbnailCmd);
            int exitCode = thumbnailProcess.waitFor();
            
            if (exitCode != 0) {
                return error("生成缩略图失败，FFmpeg返回错误码：" + exitCode);
            }
            
            if (!Files.exists(Paths.get(thumbnailFullPath))) {
                return error("缩略图文件未生成");
            }
            
            Map<String, String> result = new HashMap<>();
            result.put("thumbnail", "/images/thumbnails/" + thumbnailFilename);
            
            return success(result);
        } catch (Exception e) {
            return error("生成缩略图失败：" + e.getMessage());
        }
    }

    /**
     * 获取推广计划列表
     */
    @Anonymous
    @GetMapping("/promotion-plans")
    public AjaxResult getPromotionPlans()
    {
        // 这里应该从数据库查询推广计划，暂时返回硬编码数据
        List<Map<String, Object>> plans = new ArrayList<>();

        Map<String, Object> plan1 = new HashMap<>();
        plan1.put("id", 1);
        plan1.put("name", "首页推荐");
        plan1.put("description", "帖子显示在首页推荐位置");
        plan1.put("price", 50.00);
        plan1.put("duration", 7);
        plans.add(plan1);

        Map<String, Object> plan2 = new HashMap<>();
        plan2.put("id", 2);
        plan2.put("name", "置顶推广");
        plan2.put("description", "帖子在分类页面置顶显示");
        plan2.put("price", 30.00);
        plan2.put("duration", 3);
        plans.add(plan2);

        Map<String, Object> plan3 = new HashMap<>();
        plan3.put("id", 3);
        plan3.put("name", "热门推荐");
        plan3.put("description", "帖子显示在热门推荐区域");
        plan3.put("price", 80.00);
        plan3.put("duration", 14);
        plans.add(plan3);

        Map<String, Object> plan4 = new HashMap<>();
        plan4.put("id", 4);
        plan4.put("name", "限时闪推");
        plan4.put("description", "特定时间段内高优显示");
        plan4.put("price", 20.00);
        plan4.put("duration", 1);
        plans.add(plan4);

        Map<String, Object> plan5 = new HashMap<>();
        plan5.put("id", 5);
        plan5.put("name", "分类页首条");
        plan5.put("description", "在所属分类列表第一条显示（非置顶样式）");
        plan5.put("price", 40.00);
        plan5.put("duration", 5);
        plans.add(plan5);

        return success(plans);
    }

    /**
     * 创建支付记录
     */
    @PostMapping("/payment")
    public AjaxResult createPayment(@RequestBody PaymentRequest request)
    {
        // 检查用户是否登录
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            return error("请先登录");
        }

        if (userId == null) {
            return error("请先登录");
        }

        // 验证参数
        if (request.getPostId() == null || request.getPlanId() == null || request.getAmount() == null) {
            return error("参数不完整");
        }

        // 检查帖子是否存在且属于当前用户
        Post post = postService.selectPostById(request.getPostId());
        if (post == null) {
            return error("帖子不存在");
        }

        if (!userId.equals(post.getAuthorId())) {
            return error("只能为自己的帖子购买推广");
        }

        // 检查该帖子是否已有有效的推广支付记录
        PostPayment existingPayment = postPaymentMapper.selectLatestPaymentByPostId(request.getPostId());
        if (existingPayment != null && "paid".equals(existingPayment.getPaymentStatus())) {
            return error("该帖子已购买推广服务");
        }

        // 创建支付记录
        PostPayment payment = new PostPayment();
        payment.setPostId(request.getPostId());
        payment.setPlanId(request.getPlanId());
        payment.setUserId(userId);
        payment.setAmount(BigDecimal.valueOf(request.getAmount()));
        payment.setPaymentStatus("pending"); // 待支付状态
        payment.setPaymentTime(new Date());

        int result = postPaymentMapper.insertPostPayment(payment);

        if (result > 0) {
            return success(payment);
        } else {
            return error("创建支付记录失败");
        }
    }

    /**
     * 检查帖子推广状态
     */
    @GetMapping("/promotion-status/{postId}")
    public AjaxResult getPromotionStatus(@PathVariable Long postId)
    {
        // 检查用户是否登录
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            return error("请先登录");
        }

        if (userId == null) {
            return error("请先登录");
        }

        // 检查帖子是否存在且属于当前用户
        Post post = postService.selectPostById(postId);
        if (post == null) {
            return error("帖子不存在");
        }

        if (!userId.equals(post.getAuthorId())) {
            return error("只能查看自己的帖子推广状态");
        }

        Map<String, Object> result = new HashMap<>();
        result.put("hasPromotion", post.getPromotionPlanId() != null);
        result.put("promotionPlanId", post.getPromotionPlanId());

        // 查询最新的支付记录
        if (post.getPromotionPlanId() != null) {
            PostPayment latestPayment = postPaymentMapper.selectLatestPaymentByPostId(postId);
            result.put("latestPayment", latestPayment);
        }

        return success(result);
    }

    /**
     * 确认支付成功
     */
    @PostMapping("/payment/confirm/{paymentId}")
    public AjaxResult confirmPayment(@PathVariable Long paymentId)
    {
        // 检查用户是否登录
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            return error("请先登录");
        }

        if (userId == null) {
            return error("请先登录");
        }

        // 查询支付记录
        PostPayment payment = postPaymentMapper.selectPostPaymentById(paymentId);
        if (payment == null) {
            return error("支付记录不存在");
        }

        if (!userId.equals(payment.getUserId())) {
            return error("只能确认自己的支付记录");
        }

        if (!"pending".equals(payment.getPaymentStatus())) {
            return error("支付记录状态异常");
        }

        // 更新支付状态为成功
        payment.setPaymentStatus("paid");
        payment.setPaymentTime(new Date());
        postPaymentMapper.updatePostPayment(payment);

        // 更新帖子的推广计划ID（不管是新帖子还是现有帖子都要更新）
        if (payment.getPostId() != null && payment.getPostId() > 0) {
            Post updatePost = new Post();
            updatePost.setPostId(payment.getPostId());
            updatePost.setPromotionPlanId(payment.getPlanId());
            updatePost.setUpdateBy(getUsername());

            int result = postService.updatePost(updatePost);

            if (result <= 0) {
                return error("支付确认失败：无法更新帖子推广信息");
            }
        } else {
            return error("支付记录中的帖子ID无效");
        }

        return success("支付成功，推广已生效");
    }

    /**
     * 取消支付
     */
    @PostMapping("/payment/cancel/{paymentId}")
    public AjaxResult cancelPayment(@PathVariable Long paymentId)
    {
        // 检查用户是否登录
        Long userId = null;
        try {
            userId = getUserId();
        } catch (Exception e) {
            return error("请先登录");
        }

        if (userId == null) {
            return error("请先登录");
        }

        // 查询支付记录
        PostPayment payment = postPaymentMapper.selectPostPaymentById(paymentId);
        if (payment == null) {
            return error("支付记录不存在");
        }

        if (!userId.equals(payment.getUserId())) {
            return error("只能取消自己的支付记录");
        }

        if (!"pending".equals(payment.getPaymentStatus())) {
            return error("支付记录状态异常");
        }

        // 更新支付状态为失败
        payment.setPaymentStatus("failed");
        postPaymentMapper.updatePostPayment(payment);

        return success("支付已取消");
    }

    /**
     * 支付请求类
     */
    public static class PaymentRequest {
        private Long postId;
        private Long planId;
        private Double amount;

        public Long getPostId() {
            return postId;
        }

        public void setPostId(Long postId) {
            this.postId = postId;
        }

        public Long getPlanId() {
            return planId;
        }

        public void setPlanId(Long planId) {
            this.planId = planId;
        }

        public Double getAmount() {
            return amount;
        }

        public void setAmount(Double amount) {
            this.amount = amount;
        }
    }

    /**
     * 举报帖子
     */
    @PostMapping("/report/{postId}")
    public AjaxResult reportPost(@PathVariable Long postId, @RequestBody ReportRequest request)
    {
        // 检查用户是否登录
        Long userId = null;
        String username = null;
        try {
            userId = getUserId();
            username = getUsername();
        } catch (Exception e) {
            return error("请先登录");
        }

        if (userId == null) {
            return error("请先登录");
        }

        // 检查帖子是否存在
        Post post = postService.selectPostById(postId);
        if (post == null || !"1".equals(post.getStatus())) {
            return error("帖子不存在或已下架");
        }

        // 检查举报理由
        if (request.getReason() == null || request.getReason().trim().isEmpty()) {
            return error("举报理由不能为空");
        }

        // 创建举报记录
        PostReport report = new PostReport();
        report.setPostId(postId);
        report.setPostTitle(post.getTitle());
        report.setReportUserId(userId);
        report.setReportUserName(username);
        report.setReportReason(request.getReason());
        report.setStatus("0"); // 待处理状态
        report.setCreateBy(username);

        int result = postReportMapper.insertPostReport(report);

        if (result > 0) {
            return success("举报提交成功，我们会尽快处理");
        } else {
            return error("举报提交失败");
        }
    }

    /**
     * 举报请求类
     */
    public static class ReportRequest {
        private String reason;

        public String getReason() {
            return reason;
        }

        public void setReason(String reason) {
            this.reason = reason;
        }
    }
}